type Handler<T = unknown> = (payload: T) => void;

export class EventManager {
  private map: Map<string, Set<Handler>> = new Map();

  /**
   * @description 订阅事件
   * @param event 事件名
   * @param handler 事件处理函数
   * @returns 取消订阅函数
   */
  on(event: string, handler: Handler): () => void {
    if (!this.map.has(event)) this.map.set(event, new Set());
    const set = this.map.get(event)!;
    set.add(handler);
    return () => {
      set.delete(handler);
      if (set.size === 0) this.map.delete(event);
    };
  }

  /**
   * @description 取消订阅事件
   * @param event 事件名
   * @param handler 事件处理函数
   * @returns 是否成功取消
   */
  off(event: string, handler: Handler): boolean {
    const set = this.map.get(event);
    if (!set) return false;
    const existed = set.delete(handler);
    if (set.size === 0) this.map.delete(event);
    return existed;
  }

  /**
   * @description 派发事件
   * @param event 事件名
   * @param payload 事件数据
   * @returns void
   */
  emit<T = unknown>(event: string, payload?: T): void {
    const set = this.map.get(event);
    if (!set || set.size === 0) return;
    for (const handler of Array.from(set)) handler(payload as T);
  }

  /**
   * @description 清空所有事件订阅
   * @returns void
   */
  clear(): void {
    this.map.clear();
  }
}

